from py_stealth import *
import time

PET = 0x000F4A3D
RUNEBOOK = 0x40986270
ISRECALL = False

STORAGEBOX = 0x40F832BB
WAITTIME=800
RECALLTIME=3000
LAGWAIT=10000
HOMEINDEX=11
LOOPS = (0x0EED, 0x0F13, 0x0F10, 0x0F21, 0x0F25, 0x0F15, 0x26B7, 0x0F26, 0x0F2D, 0x0F16, 0x0F19, 0x0E21)
CRYSTALBALL=0x436167C0
lastFeedTime = time.time()

def RecallRune(index):
    global ISRECALL, RUNEBOOK
    while GetGumpsCount() > 0:
        CloseSimpleGump(0)
    result = False
    x = GetX(Self())
    y = GetY(Self())
    CheckLag(LAGWAIT)
    Wait(WAITTIME)
    UseObject(RUNEBOOK)
    CheckLag(LAGWAIT)
    Wait(WAITTIME)
    if IsGump():
        rune_book_shift = 5
        if not ISRECALL:
            rune_book_shift = 7
        if NumGumpButton(GetGumpsCount()-1, rune_book_shift + (6*index)):
            CheckLag(LAGWAIT)
            Wait(RECALLTIME)
            CheckLag(LAGWAIT)
            result = (x != GetX(Self())) or (y != GetY(Self()))
        else:
            result = False
    else:
        result = False
    return result

def LoopCorpse():
    SetFindDistance(22)
    while FindType(0x2006, Ground()) > 0:
        corpses = GetFindedList()
        for corpse in corpses:
            AddToJournal('start loop: '+GetTooltip(corpse))
            NewMoveXY(GetX(corpse), GetY(corpse), False, 1, True)
            UseObject(corpse)
            Wait(WAITTIME)
            for loop_type in LOOPS:
                if FindType(loop_type, corpse) > 0:
                    Grab(FindItem(), FindQuantity())
                    CheckLag(LAGWAIT)
                    Wait(WAITTIME)
            Ignore(corpse)
            AddToJournal('loop end')

def GetNearEnemyCount():
    enemy_list = []
    SetFindDistance(18)
    FindType(-1, Ground())
    for found in GetFindedList():
        #print(GetTooltip(found)+str(GetNotoriety(found)))
        if GetNotoriety(found) > 2:
            enemy_list.append(found)
    return len(enemy_list)

def NextPoint(pointIndex):
    Wait(WAITTIME)
    WaitNext()
    for i in range(3):
        AddToJournal('reall point->'+str(pointIndex)+' retry->'+str(i+1))
        NewMoveXY(GetX(PET), GetY(PET), False, 1, True)
        if RecallRune(pointIndex):
            AddToJournal('reall point->'+str(pointIndex)+' success')
            return

def WaitNext():
    while abs(GetX(PET) - GetX(Self())) + abs(GetY(PET) - GetY(Self())) > 2 \
            or GetMana(Self()) < 10 \
            or GetNearEnemyCount() > 0:
        AddToJournal('wait NextPoint')
        Wait(1000)

def BackHome():
    global HOMEINDEX, LOOPS, PET, lastFeedTime, CRYSTALBALL, LAGWAIT
    #if MaxWeight() < Weight() + 50:
    WaitNext()
    AddToJournal('back home storege items')
    RecallRune(HOMEINDEX)
    Wait(3000)
    NewMoveXY(2075, 1293, False, 0, True)
    Wait(3000)
    UseObject(STORAGEBOX)
    Wait(WAITTIME)
    for item_type in LOOPS:
        if FindType(item_type, Backpack()) > 0:
            CheckLag(LAGWAIT)
            Wait(WAITTIME)
            MoveItem(FindItem(), FindQuantity(), STORAGEBOX, 0, 0, 0)
    AddToJournal('storege all items end')
    if FindType(0x0E21, STORAGEBOX) > 0:
        CheckLag(LAGWAIT)
        Wait(WAITTIME)
        MoveItem(FindItem(), 300, Backpack(), 0, 0, 0)
        AddToJournal('grab bandage end')

    pet_distance = abs(GetX(PET) - GetX(Self())) + abs(GetY(PET) - GetY(Self()))
    if pet_distance > 20:
        AddToSystemJournal('not found pet')
        UseObject(CRYSTALBALL)
        CheckLag(LAGWAIT)
        Wait(3000)

    current_time = time.time()
    if abs(lastFeedTime - current_time) > 60 * 60 and FindType(0x09F1, STORAGEBOX) > 0:
        CheckLag(LAGWAIT)
        Wait(WAITTIME)
        MoveItem(FindItem(), 1, PET, 0, 0, 0)
        lastFeedTime = current_time
        AddToJournal('feed pet end')


def Heal():
    global PET
    AddToJournal('check hp')
    while GetHP(PET) < GetMaxHP(PET) * 0.8 and FindType(0x0E21, Backpack()) > 0:
        if TargetPresent():
            CancelTarget()
        NewMoveXY(GetX(PET), GetY(PET), False, 1, True)
        UseObject(FindItem())
        CheckLag(LAGWAIT)
        Wait(3000)
        WaitTargetObject(PET)
        CheckLag(LAGWAIT)
        Wait(WAITTIME)
        AddToJournal('heal pet')
    while GetHP(Self()) < GetMaxHP(Self()):
        if TargetPresent():
            CancelTarget()
        if GetMana(Self()) > 20:
            CheckLag(LAGWAIT)
            Wait(WAITTIME)
            CastToObj('Close Wounds', Self())
            AddToJournal('heal self')
        else:
            Wait(WAITTIME)
            AddToJournal('wait mana form heal')

def Main():
    UOSay('all guard me')
    CheckLag(LAGWAIT)
    Wait(WAITTIME)
    while not Dead():
        for pointIndex in (7, 8, 9, 10):
            BackHome()
            NextPoint(pointIndex)
            while GetNearEnemyCount() > 0:
                AddToJournal('wait near enemy dead')
                Heal()
                Wait(WAITTIME)
            LoopCorpse()
            Wait(WAITTIME)

Main()